/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __BLENDER_MESH_LOAD_IMPL_H__
#define __BLENDER_MESH_LOAD_IMPL_H__

#include "GPrerequisites.h"

#include "OgreVertexBoneAssignment.h"
#include "OgreResource.h"

#include "blender.h"
#include "bMain.h"
#include "bBlenderFile.h"

#include "BlenderLoadUtil.h"
#include "MeshFace.h"
#include "SubMeshBuffer.h"

namespace GNgine
{
	typedef std::vector<int> BoneAssignIndexList;
	typedef std::vector<Ogre::VertexBoneAssignment> BoneAssignList;
	typedef std::map<int, BoneAssignList> BoneAssignListMap;

	/** Internal class that used to load blender mesh data into Ogre mesh.
        @remarks
			This class shouldn't used by user,just an implementation of blender mesh loader.
    */
	class BlenderMeshLoadImpl
	{
	public:
		BlenderMeshLoadImpl(bParse::bBlenderFile* blenderFile,Blender::Object *object,  Ogre::Mesh *mesh);

		void load(void);//load mesh data into ogre

	private:
		void convertMeshFace(int faceIndex);
		void splitQuadFace(int faceIndex,MeshFace* tri);
		void addTriFace(int faceIndex,MeshFace* tri);
		//load mesh into Ogre
		void createMesh();
		void createSubMesh(int index);
		void createSubMeshMaterial(int index);

		//create vertex declaration according to specific submesh
		int createVertexDeclaration(Ogre::SubMesh* submesh);

		void convertSkeleton(Ogre::Skeleton *skel, BoneAssignListMap &assignList,  BoneAssignIndexList& index);
		void findWeight(int index, SubMeshItem* item);

	private:
		bParse::bBlenderFile* _bFile;
		Blender::Object *_bObject;
		Blender::Mesh* _bMesh;
		Blender::MTFace* _bLayers[8];
		Blender::MCol * _bMcol;

		BlenderLoadUtil* _loader;
		int _validLayers;
		bool _opengl;//use _opengl
		int _materialIndex;

		SubMeshBufferLookup _submeshBuffer;//store submesh data?
		//Mesh AABB
		Ogre::Vector3 _minAABB;
		Ogre::Vector3 _maxAABB;
		Ogre::Real _radiusAABB;

		BoneAssignIndexList _boneIndices;
		BoneAssignListMap _boneAssignments;

		Ogre::Mesh *_mesh;
		Ogre::String _skeletonName;
	};
}

#endif
